import { post, get } from "@/utils/request";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { type AxiosPromise } from "axios";
import z from "zod";
import { toast } from "sonner";

export const uploadKeys = {
  all: () => ["uploads"],
};

export interface UploadsQueryParams {
  [key: string]: unknown;
}

export const uploads = (data: UploadsQueryParams = {}): AxiosPromise => {
  return get("/uploads", data);
};

export interface UploadDeleteData {
  id: number[];
}

export const uploadDelete = (data: UploadDeleteData): AxiosPromise => {
  return post("/uploads/delete", data);
};

export function useUploadDelete() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (data: UploadDeleteData) => {
      return uploadDelete(data);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: uploadKeys.all() });
    },
  });
}

// 更新上传文件接口
export interface UploadUpdateData {
  id: number;
  name?: string;
  category?: string;
  [key: string]: unknown;
}

export const uploadUpdate = (data: UploadUpdateData): AxiosPromise => {
  return post("/uploads/update", data);
};

export function useUploadUpdate() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (data: UploadUpdateData) => {
      return uploadUpdate(data);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: uploadKeys.all() });
    },
  });
}

/**
 * 上传文件API
 * @param file 要上传的文件
 * @param onProgress 上传进度回调函数
 * @returns 上传结果，包含文件URL
 */
interface UploadParams {
  file: File;
  category: string;
  onProgress?: (percent: number) => void;
}

/**
 * 文件上传结果接口
 */
const _uploadResponseSchema = z.object({
  code: z.number(),
  msg: z.string(),
  count: z.number().optional(),
  data: z
    .object({
      url: z.string(),
    })
    .optional(),
});

export type UploadResponse = z.infer<typeof _uploadResponseSchema>;

const handleUpload = (
  endpoint: string,
  file: File,
  category: string,
  onProgress?: (percent: number) => void
): AxiosPromise => {
  // 节流处理进度回调
  const throttledProgress = (percent: number) => {
    if (onProgress) {
      requestAnimationFrame(() => onProgress(percent));
    }
  };
  return post(endpoint, { category }, file, throttledProgress);
};

const uploadFile = (
  file: File,
  category: string,
  onProgress?: (percent: number) => void
): AxiosPromise => {
  return handleUpload("/uploads/file", file, category, onProgress);
};

const uploadAvatar = (
  file: File,
  onProgress?: (percent: number) => void
): AxiosPromise => {
  return handleUpload("/uploads/avatar", file, "avatar", onProgress);
};

/**
 * 使用文件上传钩子
 * @returns 文件上传mutation对象
 */
export const useFileUpload = () => {
  return useMutation({
    mutationFn: async ({ file, category, onProgress }: UploadParams) => {
      try {
        return await uploadFile(file, category, onProgress);
      } catch (error) {
        if (error instanceof Error) {
          toast.error(`文件上传失败: ${error.message}`);
        } else {
          toast.error("文件上传失败");
        }
        throw error;
      }
    },
  });
};

/**
 * 使用头像上传钩子
 * @returns 头像上传mutation对象
 */
export const useAvatarUpload = () => {
  return useMutation({
    mutationFn: async ({
      file,
      onProgress,
    }: Omit<UploadParams, "category">) => {
      return uploadAvatar(file, onProgress);
    },
  });
};
